package com.example.httplibrary.mvp.proxy;




import com.example.httplibrary.mvp.BasePresenter;
import com.example.httplibrary.mvp.BaseView;
import com.example.httplibrary.mvp.inject.InjectPresenter;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

/**
 * Author: 李巷阳
 * Date: 2020/6/6
 * Part:实现
 * Description:
 */
public class MvpProxyImpl<V extends BaseView> implements IMvpProxy {
    private V mView;
    public List<BasePresenter> mPresenters;

    public MvpProxyImpl(V view) {
        // 做一下判断 是不是 NULL
        this.mView = view;
        mPresenters = new ArrayList<>();
    }

    @Override
    public void bindAndCreatePresenter(AppCompatActivity mActivity) {

    }

    @Override
    public void bindAndCreatePresenter(Fragment mFragment) {

    }


    public void bindAndCreatePresenter() {
        // 这个地方要去注入 Presenter 通过反射 (Dagger) soEasy
        Field[] fields = mView.getClass().getDeclaredFields();
        for (Field field : fields) {
            InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
            if (injectPresenter != null) {

                // 创建注入
                Class<? extends BasePresenter> presenterClazz  = (Class<? extends BasePresenter>) field.getType();
                // 判断这个class 是不是继承自BasePresenter 如果不是则抛异常
                if (!BasePresenter.class.isAssignableFrom(presenterClazz)) {
                    throw new RuntimeException("No support inject presenter type " + presenterClazz.getName());
                }

                // 创建 Presenter 对象
                BasePresenter basePresenter=null;
                try {
                    basePresenter = presenterClazz.newInstance();
                    // 并没有解绑，还是会有问题，这个怎么办？1 2
                    basePresenter.attach(mView);

                    // 设置
                    field.setAccessible(true);
                    field.set(mView, basePresenter);
                    mPresenters.add(basePresenter);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                // 检测我们的 view 层是否实现了 BasePresenter 的View接口
                checkView(basePresenter);


            }
        }
    }
    /**
     * 检测我们的 View 层是否实现了 BasePresenter 的View接口
     * @param basePresenter
     */
    private void checkView(BasePresenter basePresenter) {
        if(basePresenter==null)
            return;
        // 1. Presenter 的 View 接口
        Type[] params = ((ParameterizedType) basePresenter.getClass().getGenericSuperclass()).getActualTypeArguments();
        Class viewClazz = ((Class)params[0]);

        // 2. 要拿到 View 层的所有接口
        Class[] ViewClasses = mView.getClass().getInterfaces();
        // 3. View层没有实现就抛异常
        boolean isImplementsView = false;
        for (Class viewClass : ViewClasses) {
            if(viewClass.isAssignableFrom(viewClazz)){
                isImplementsView = true;
            }
        }
        if(!isImplementsView){
            throw new RuntimeException(mView.getClass().getSimpleName()+" must implements "+viewClazz.getName());
        }
    }
//    @Override
//    public void unbindPresenter() {
//        // 一定要解绑
//        for (BasePresenter presenter : mPresenters) {
//            presenter.detach();
//            Log.e("unbindPresenter","解绑");
//        }
//        mView = null;
//    }
}
